﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.ZLog;

namespace UtilZ.Dotnet.Ex.Communication.Net.Ftp
{
    /// <summary>
    /// 设置或显示文件传输类型（ASCII/二进制) A/I.
    /// Sets the transfer mode (ASCII/Binary).
    /// </summary>
    internal class FtpTYPECommand : FtpCommandAbs
    {
        /***********************************************************************************************************
        * [TYPE]（Representation Type,表达类型）命令
        * 说明：确定数据的传输方式。
        * 
        * 用法：TYPE<Data Type Code><CRLF>
        * 参数：Data type Code是一个（或几个）ASCII字符，它标识出一种数据表达类型。
        * 例子：
        * ‘—设置二进制模式
        * SendData "type I" + “/r/n
        * 
        * 注释：最典型的情况就是使用TYPE命令在ASCII或二进制模式（Image，图像）之间切换。发送和接收任何类型的文件时都可以使用图像类型。ASCII类型只在传送文本时使用。
        * 有几种类型要用到第二个参数。第一个参数由一个单独的ASCII字符表示，ASCII和EBCDIC的第二个Format参数也是如此；本地字节的 第二个参数则是一个表示Byte大小的十进制整数。两个参数之间用<SP>（Space，即空格，ASCII代码为32）分隔开。
        * 给类型分配如下代码：
        * A——ASCII*
        * E——EBCDIC*
        * I——Image（图像，传送二进制文件时用它）。
        * L<byte size>——Local byte  Byte size（本地字节，字节大小）
        * 
        * -------------------------------------
        * 
        * *——A和E类型的第二个Parameter要用到如下三个的其中一个：
        * N——Nonprint（非打印）
        * T——Telnet format effector（Telnet格式控制符）
        * C——Carriage Control（ASA）托架控制（美国国家标准）。
        * 默认的表达类型是ASCII Nonprint。如果Format参数发生改变，后来只是第一个参数发生了改变，Format将随即返回到默认的Nonprint。
        * 返回值如下（粗体表示成功）：
        * 200  命令成功。
        * 421  服务不可用，关闭控制连接。
        * 
        * 如果某项服务获知自己即将关闭，会向所有命令做出这个应答
        * 500  语法错误，无法识别命令。这其中包括命令行过长之类的错误。
        * 501  参数或变元中有语法错误。
        * 504  命令中还没有实现该参数。
        * 530  无法登录。
        * 
        ************************************************************************************************************/


        public FtpTYPECommand()
            : base()
        {

        }


        protected override string[] GetNames()
        {
            return new string[] { FtpCommands.TYPE };
        }


        protected override IFtpResponse PrimitiveExcute(FtpSession session, string command, string commandLine)
        {
            //Request: TYPE A
            //Response: 200 Type set to A.
            //或
            //Response: 200 Type set to I.

            try
            {
                if (string.IsNullOrWhiteSpace(commandLine))
                {
                    return new FtpCodeResponse(FtpStatusCodes.Code501);
                }

                IFtpResponse res;
                switch (commandLine.ToUpper())
                {
                    case "A":
                        session.DataTransferFormat = FtpDataTransferFormats.ASCII;
                        res = new FtpCodeResponse(FtpStatusCodes.Code200, "Type set to A.");
                        break;
                    case "I":
                        session.DataTransferFormat = FtpDataTransferFormats.Image;
                        res = new FtpCodeResponse(FtpStatusCodes.Code200, "Type set to I.");
                        break;
                    case "E":
                        session.DataTransferFormat = FtpDataTransferFormats.EBCDIC;
                        res = new FtpCodeResponse(FtpStatusCodes.Code200, "Type set to E.");
                        break;
                    default:
                        res = new FtpCodeResponse(FtpStatusCodes.Code504);
                        break;
                }

                return res;
            }
            catch (Exception ex)
            {
                return new FtpCodeResponse(FtpStatusCodes.Code451, ex.Message);
            }
        }
    }

}
